﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XCommunity.Documents;
using System.Xml.Linq;
using System.Globalization;

namespace XCommunity.Frames
{

  /// <summary>
  /// 一般性的帖子，GeneralTopicFrame的组成。
  /// </summary>
  public class GeneralPostFrame : IPostFrame
  {



    /// <summary>
    /// 创建一个帖子对象
    /// </summary>
    /// <param name="topic">所在话题</param>
    protected internal GeneralPostFrame( GeneralTopicFrame topic )
    {
      _topic = topic;
    }



    /// <summary>
    /// 获取框架服务
    /// </summary>
    public FrameService Service
    {
      get { return Topic.Service; }
    }



    /// <summary>
    /// 贴子原作者
    /// </summary>
    public string Author
    {
      get
      {
        return FrameData.Element( "Author" ).Value;
      }
    }



    /// <summary>
    /// 该帖子当前版本文档（需要被呈现的文档）
    /// </summary>
    public PublishedDocument CurrentVersion
    {
      get
      {
        return Service.GetDocument( Topic, int.Parse( FrameData.Element( "Current" ).Element( "Document" ).Attribute( "ID" ).Value ) );
      }
    }


    /// <summary>
    /// 该帖子的历史版本
    /// </summary>
    public IEnumerable<PublishedDocument> HistoricalVersions
    {
      get
      {
        return FrameData.Elements( "Historical" ).Select( element => Service.GetDocument( Topic, int.Parse( element.Element( "Document" ).Attribute( "ID" ).Value ) ) );
      }
    }

    /// <summary>
    /// 获取帖子所有的版本
    /// </summary>
    /// <returns></returns>
    public IEnumerable<PublishedDocument> GetAllVersions()
    {
      yield return CurrentVersion;
      foreach ( PublishedDocument document in HistoricalVersions )
        yield return document;
    }


    private GeneralTopicFrame _topic;

    /// <summary>
    /// 该帖子所属的话题
    /// </summary>
    ITopicFrame IPostFrame.Topic
    {
      get { return Topic; }
    }


    /// <summary>
    /// 该帖子所属的话题
    /// </summary>
    public GeneralTopicFrame Topic
    {
      get { return _topic; }
    }



    private Guid? _guid;

    /// <summary>
    /// 该帖子的唯一标识
    /// </summary>
    public Guid Guid
    {
      get
      {

        if ( _guid == null )
          _guid = new Guid( FrameData.Attribute( "GUID" ).Value );

        return (Guid) _guid;
      }
    }


    /// <summary>
    /// 帖子发布的时间
    /// </summary>
    public DateTime PublishDate
    {
      get
      {
        return DateTime.Parse( FrameData.Attribute( "PublishDate" ).Value ).ToUniversalTime();
      }
    }

    /// <summary>
    /// 帖子最后修改时间
    /// </summary>
    public DateTime LastModifyDate
    {
      get { return GetAllVersions().Max( document => document.PublishDate ); }
    }


    /// <summary>
    /// 指示该帖子是不是话题的主题
    /// </summary>
    public bool IsTheme
    {
      get { return Topic.Theme.Guid == Guid; }
    }



    /// <summary>
    /// 指示该帖子是否已经被移除
    /// </summary>
    /// <remarks>帖子可以从话题移除，但信息仍然会保留在话题中。</remarks>
    public bool Removed
    {
      get
      {
        XAttribute removedAttribute = FrameData.Attribute( "Removed" );
        if ( removedAttribute != null )
          return Convert.ToBoolean( removedAttribute.Value );
        else
          return false;
      }
    }


    /// <summary>
    /// 指示该帖子是否已经被隐藏
    /// </summary>
    public bool Hidden
    {
      get
      {
        XAttribute hiddenAttribute = FrameData.Attribute( "Hidden" );
        if ( hiddenAttribute != null )
          return Convert.ToBoolean( hiddenAttribute.Value );
        else
          return false;
      }
    }



    private XElement _frameData;

    /// <summary>
    /// 获取帖子的框架数据
    /// </summary>
    protected internal XElement FrameData
    {
      get { return _frameData; }
    }


    /// <summary>
    /// 指示此帖子是否已被加载
    /// </summary>
    public bool Loaded
    {
      get;
      protected set;
    }


    /// <summary>
    /// 加载框架数据
    /// </summary>
    /// <param name="frameData"></param>
    public virtual void Load( XElement frameData )
    {
      _frameData = frameData;

      if ( FrameData.Attribute( "PublishDate" ) == null )
        FrameData.Add( new XAttribute( "PublishDate", GetAllVersions().Min( document => document.PublishDate ).ToString( "u" ) ) );

      Loaded = true;
    }


    /// <summary>
    /// 保存框架数据
    /// </summary>
    /// <returns></returns>
    public virtual XElement Save()
    {
      return _frameData;
    }


    /// <summary>
    /// 修改帖子时，GeneralTopicFrame调用此方法。
    /// </summary>
    /// <param name="document"></param>
    internal void ExecuteModifyPost( PublishedDocument document )
    {
      if ( document.TopicId != Topic.TopicId )
        throw new Exception();//UNDONE 异常详细信息

      FrameData.Element( "Current" ).Name = "Historical";
      FrameData.Add( new XElement( "Current", new XElement( "Document", new XAttribute( "ID", document.DocumentId ) ) ) );
    }


    /// <summary>
    /// 移除一个回复时，GeneralTopicFrame调用此方法。
    /// </summary>
    internal void ExecuteRemovePost()
    {
      FrameData.SetAttributeValue( "Removed", true );
    }

    internal void ExecuteHidePost()
    {
      FrameData.SetAttributeValue( "Hidden", true );
    }

    internal void ExecuteUnhidePost()
    {
      FrameData.SetAttributeValue( "Hidden", false );
    }
  }
}
